package top.cluski.feieprint.service;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.dtflys.forest.Forest;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import top.cluski.feieprint.api.maiyatian.MaiyatianWebhookApi;
import top.cluski.feieprint.api.maiyatian.domain.vo.WebhookOrderSummaryVO;
import top.cluski.feieprint.api.teable.TeableApi;
import top.cluski.feieprint.api.teable.entity.Filter;
import top.cluski.feieprint.api.teable.entity.FilterItem;
import top.cluski.feieprint.api.teable.entity.RecordAddDTO;
import top.cluski.feieprint.api.teable.entity.RecordEntity;
import top.cluski.feieprint.config.TeableConfig;
import top.cluski.feieprint.domain.dto.WuliaoListenerDTO;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

import static cn.hutool.core.date.DatePattern.NORM_DATE_FORMATTER;
import static top.cluski.feieprint.api.teable.entity.Filter.Conjunction.and;
import static top.cluski.feieprint.api.teable.entity.Filter.Operator.is;
import static top.cluski.feieprint.api.teable.entity.Filter.Operator.isNotEmpty;
import static top.cluski.feieprint.api.teable.entity.FilterItem.TimeFilterValue.today;
import static top.cluski.feieprint.api.teable.entity.FilterItem.TimeFilterValue.yesterday;

@Service
@Slf4j
public class TeableService {
    @Resource
    TeableConfig teableConfig;

    @Resource
    TeableApi teableApi;
    @Resource
    MaiyatianWebhookApi maiyatianWebhookApi;

    public JSONObject getRecord() {
        String resp = Forest.get("https://app.teable.cn/api/table/" + teableConfig.getTableId() + "/record?cellFormat=json&fieldKeyType=name&take=1&skip=0")
                .addHeader("Authorization", "Bearer " + teableConfig.getToken())
                .executeAsString();

        JSONObject jsonObject = JSONObject.parseObject(resp);

        JSONObject result = new JSONObject();
        JSONArray records = jsonObject.getJSONArray("records");
        JSONObject fields = records.getJSONObject(0).getJSONObject("fields");
        for (Map.Entry<String, Object> entry : fields.entrySet()) {
            if (entry.getValue() instanceof String
                    || entry.getValue() instanceof Integer
                    || entry.getValue() instanceof Double
                    || entry.getValue() instanceof JSONArray) {
                result.put(entry.getKey(), entry.getValue());
            }
        }
        return result;
    }

    @Scheduled(cron = "0 0 20 * * ?")
    public void scheduleDriverFee() {
        List<RecordEntity> records = teableApi.getRecords("tblMfOIw8Y33olmwP8w", Filter.create()
                .setConjunction(and)
                .setFilterSet(Set.of(
                        FilterItem.<FilterItem.TimeFilterValue>create().setFieldId("日期").setOperator(is).setValue(today()),
                        FilterItem.<String>create().setFieldId("配送师傅").setOperator(isNotEmpty).setValue("")
                ))
        );

        Map<String, Double> driverFeeMap = new HashMap<>();
        Map<String, Integer> driverCountMap = new HashMap<>();

        for (RecordEntity record : records) {
            String driverName = "";
            StringBuilder feeBuilder = new StringBuilder();
            for (String key : record.getFields().keySet()) {
                if ("运费".equals(key)) {
                    feeBuilder.append(record.getFields().getString(key));
                } else if ("配送师傅".equals(key)) {
                    driverName = record.getFields().getString(key);
                    driverCountMap.compute(driverName, (k, v) -> v == null ? 1 : v + 1);
                }
            }
            String finalFee = feeBuilder.toString();
            if (StrUtil.isNotBlank(finalFee) && StrUtil.isNotBlank(driverName)) {
                driverFeeMap.compute(driverName, (k, v) -> v == null ? Double.parseDouble(finalFee) : v + Double.parseDouble(finalFee));
            }
        }

        List<RecordEntity> driverRecords = teableApi.getRecords("tblEXyfnshAviHoeEFz", null);

        // 插入 运费每日汇总 表
        for (RecordEntity driverRecord : driverRecords) {
            driverFeeMap.entrySet().stream().filter(entry -> entry.getKey().equals(driverRecord.getName()))
                    .findAny()
                    .ifPresent(entry -> {
                        if (entry.getValue() != null) {
                            RecordAddDTO recordAddDTO = RecordAddDTO.create(Map.of("日期", LocalDate.now().format(NORM_DATE_FORMATTER),
                                    "师傅名称", driverRecord.getId(),
                                    "当日运费", entry.getValue().toString(),
                                    "当日单数", driverCountMap.getOrDefault(driverRecord.getName(), 0)));
                            teableApi.addRecords("tblbLSXeOnHK4ai0FWP", List.of(recordAddDTO));
                        }
                    });
        }

        // 插入 运费汇总 表
        List<String> driverNames = driverRecords.stream().map(item -> item.getFields().getString("师傅名称")).toList();
        Map<String, Object> fields = driverFeeMap.entrySet().stream()
                .filter(entry -> driverNames.contains(entry.getKey()) || entry.getKey().equals("麦芽田-跑腿") || entry.getKey().equals("麦芽田-汽车"))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        fields.put("日期", LocalDate.now().format(NORM_DATE_FORMATTER));
        teableApi.addRecords("tblzuPyRLA2ARHrgPF5", List.of(RecordAddDTO.create(fields)));
    }

    @Scheduled(cron = "0 0 5 * * ?")
    public void scheduleMaiyatianFee() {
        Map<String, Object> feeMap = new HashMap<>();

        try {
            WebhookOrderSummaryVO yesterdayOrderSummary = maiyatianWebhookApi.getYesterdayOrderSummary();
            feeMap.put("麦芽田-跑腿", yesterdayOrderSummary.getPaotui().doubleValue() / 100);
            feeMap.put("麦芽田-汽车", yesterdayOrderSummary.getQiche().doubleValue() / 100);

        } catch (Exception e) {
            log.error("麦芽田webhook调用失败", e);
            return;
        }
        String day = LocalDate.now().minusDays(1).format(NORM_DATE_FORMATTER);
        List<RecordEntity> records = teableApi.getRecords("tblzuPyRLA2ARHrgPF5", Filter.create()
                .setConjunction(and)
                .setFilterSet(Set.of(FilterItem.<FilterItem.TimeFilterValue>create().setFieldId("日期").setOperator(is).setValue(yesterday()))));
        if (records.isEmpty()) {
            log.error("没有查询到 {} 的运费汇总记录", day);
            return;
        }
        RecordEntity recordEntity = records.get(0);
        String recordId = recordEntity.getId();

        // 更新 运费汇总 表
        teableApi.updateRecord("tblzuPyRLA2ARHrgPF5", recordId, RecordAddDTO.create(feeMap));
    }

    public void wuliaoListener(WuliaoListenerDTO wuliaoListenerDTO) {
        RecordEntity teableApiRecord = teableApi.getRecord("tblKrzEMyci3bCcECRT", wuliaoListenerDTO.getRecordId());
        JSONObject fields = teableApiRecord.getFields();
        Double nowStore = fields.getDouble("当前库存");
        Double beforeStore = fields.getDouble("上次库存");
        if (Objects.equals(nowStore, beforeStore)) {
            return;
        }
        String type = "入库";
        if (nowStore < beforeStore) {
            type = "出库";
        }

        String desc = "";
        // 在0点前后5分钟
        LocalTime now = LocalTime.now();
        if ((now.getHour() == 23 && now.getMinute() >= 55) || (now.getHour() == 0 && now.getMinute() <= 5)) {
            desc = "每日自动扣减用量";
        }

        // 增加记录
        teableApi.addRecords("tblQiiAHs5Wg8Nprp7Q", List.of(RecordAddDTO.create(
                Map.of("物料", fields.getString("物料名称"),
                        "操作类型", type,
                        "数量", Math.abs(nowStore - beforeStore),
                        "描述", desc)
        )));

        // 修改记录
        teableApi.updateRecord("tblKrzEMyci3bCcECRT", teableApiRecord.getId(), RecordAddDTO.create(
                Map.of("上次库存", nowStore)
        ));
    }

    @Scheduled(cron = "59 59 23 * * ?")
    public void wuliaoAutoMinus() {
        List<RecordEntity> records = teableApi.getRecords("tblKrzEMyci3bCcECRT", Filter.create()
                .setConjunction(and).setFilterSet(Set.of()));
        for (RecordEntity record : records) {
            JSONObject fields = record.getFields();
            // 修改记录
            teableApi.updateRecord("tblKrzEMyci3bCcECRT", record.getId(), RecordAddDTO.create(
                    Map.of("当前库存", fields.getDouble("当前库存") - fields.getDouble("每日用量"))
            ));
        }
    }
}
